﻿//==================================================================
// Copyright (C) 2011 iSun Studio 软件工作室
// 作 者：江怀玉
// Email:iSunStudio@hotmail.com
// 日 期：2011-10-14
// 描 述：扩展一些常用方法，含MD5加密,验证,JSON串处理
// 版 本：1.00
// 修改历史纪录
// 版 本  修改时间      修改人            修改内容
//==================================================================
using System;
using System.Collections.Generic;
using System.Text;
using System.Security.Cryptography;
using iSun.Model;
using System.Text.RegularExpressions;
using System.Collections;
using System.Linq;

namespace iSun.Common
{
   /// <summary>
    /// 扩展属性
    /// </summary>
    public static class ExtendMethods
    {
        // Hash an input string and return the hash as
        // a 32 character hexadecimal string.
        public static string GetMd5Hash(this string input)
        {
            // Create a new instance of the MD5CryptoServiceProvider object.
            MD5 md5Hasher = MD5.Create();

            // Convert the input string to a byte array and compute the hash.
            byte[] data = md5Hasher.ComputeHash(Encoding.Default.GetBytes(input));

            // Create a new Stringbuilder to collect the bytes
            // and create a string.
            StringBuilder sBuilder = new StringBuilder();

            // Loop through each byte of the hashed data 
            // and format each one as a hexadecimal string.
            for (int i = 0; i < data.Length; i++)
            {
                sBuilder.Append(data[i].ToString("x2"));
            }

            // Return the hexadecimal string.
            return sBuilder.ToString();
        }

        // Verify a hash against a string.
        public static bool VerifyMd5Hash(this string input, string hash)
        {
            // Hash the input.
            string hashOfInput = input.GetMd5Hash();

            // Create a StringComparer an comare the hashes.
            StringComparer comparer = StringComparer.OrdinalIgnoreCase;

            if (0 == comparer.Compare(hashOfInput, hash))
            {
                return true;
            }

            return false;
        }


        /// <summary>
        /// 扩展Entity功能，可以直接转换成JSON数据格式
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public static string ToJSON(this BaseEntity entity)
        {
            return Globals.getJSON(entity);
        }


        public static string ToJSON(this IList<BaseEntity> list) 
        {
            //return Globals.ObjectToJSON(list);
            return Globals.getJSON<BaseEntity>(list);
        }

        public static string ToJSON(this object[] list)
        {
            return Globals.ObjectToJSON(list);
        }
        
        /// <summary>
        /// 用于正则表达式
        /// </summary>
        /// <param name="item"></param>
        /// <param name="searchPattern"></param>
        /// <returns></returns>
        public static bool Like(this string item, string searchPattern)
        {
            return GetRegex("^" + searchPattern).IsMatch(item);
        }
        /*
         * example 
         * 
           example：一个字符串是一个guid。
             var result = "TA0E02391-A0DF-4772-B39A-C11F7D63C495".Like("????????-????-????-????????????");  
            example：guid结尾的字符串。
             var result = "This is a guid TA0E02391-A0DF-4772-B39A-C11F7D63C495".Like("
            %????????-????-????-????????????");
         * 
         */

        /// <summary>
        /// 搜索
        /// </summary>
        /// <param name="item"></param>
        /// <param name="searchPattern"></param>
        /// <returns></returns>
        public static string Search(this string item, string searchPattern)
        {
            var match = GetRegex(searchPattern).Match(item);
            if (match.Success)
            {
                return item.Substring(match.Index, match.Length);
            }
            return null;
        }
        /*
         * example
         * 
         var result = "this string [TA0E02391-A0DF-4772-B39A-C11F7D63C495] contains a string matching".Search("[????????-????-????-????????????]")
    Console.WriteLine(result); // output: [TA0E02391-A0DF-4772-B39A-C11F7D63C495] 
         * 
         */

        /// <summary>
        /// 
        /// </summary>
        /// <param name="item"></param>
        /// <param name="searchPattern"></param>
        /// <returns></returns>
        public static List<string> Extract(this string item, string searchPattern)
        {
            var result = item.Search(searchPattern);
            if (!string.IsNullOrWhiteSpace(result))
            {
                string[] splitted = searchPattern.Split(new[] { '?', '%', '*', '#' }, StringSplitOptions.RemoveEmptyEntries);
                var temp = result;
                var final = new List<string>();
                Array.ForEach(splitted,x =>
                {
                    var pos = temp.IndexOf(x);
                    if (pos > 0)
                    {
                        final.Add(temp.Substring(0, pos));
                        temp = temp.Substring(pos);
                    }
                    temp = temp.Substring(x.Length);
                });
                if (temp.Length > 0) final.Add(temp);
                return final;
            }
            return null;
        }
        /*example 
         * 
         * var result = "this string [TA0E02391-A0DF-4772-B39A-C11F7D63C495] contains a string matching".Extract("[????????-????-????-????????????]");
         // result is an array containing each part of the pattern: {"TA0E02391", "A0DF", "4772", "B39A", "C11F7D63C495"} 
         example: 在一个字符串中返回email的构成部分
 var result = "this string contains an email: toto@domain.com".Extract("*?@?*.?*")
    // result is an array containing each part of the pattern: {"toto", "domain", "com"}
         * 
         * 
         */


        // private method which accepts the simplified pattern and transform it into a valid .net regex pattern:
        // it escapes standard regex syntax reserved characters 
        // and transforms the simplified syntax into the native Regex one
        static Regex GetRegex(string searchPattern)
        {
            return new Regex(searchPattern
                    .Replace("\\", "\\\\")
                    .Replace(".", "\\.")
                    .Replace("{", "\\{")
                    .Replace("}", "\\}")
                    .Replace("[", "\\[")
                    .Replace("]", "\\]")
                    .Replace("+", "\\+")
                    .Replace("$", "\\$")
                    .Replace(" ", "\\s")
                    .Replace("#", "[0-9]")
                    .Replace("?", ".")
                    .Replace("*", "\\w*")
                    .Replace("%", ".*")
                    , RegexOptions.IgnoreCase);
        }
    }
}

